package javabasics;

/**switch
 * 参数可以是整数表达式，JDK1.5开始支持Enum类，JDK1.7开始支持String。在jdk
 * 7 之前，switch 只能支持 byte、short、char、int 这几个基本数据类型和其对应的封装
 * 类型。switch后面的括号里面只能放int类型的值，但由于byte，short，char类型，它
 * 们会 自动 转换为int类型（精精度小的向大的转化），所以它们也支持。
 * 注意，对于精度比 int大的类型，比如 long、float，doulble，不会自动转换为 int，如
 * 果想使用，就必须强转为 int，如(int)float;
 * 当字符串不会频繁改变时可以用枚举来代替String：用Enum.parse。
 * */
public class TestSwitch {
    public static void testSwitch(){
//        String bb = "a";
//        Byte bb = 9;
        float bb = 9.0f;
        int ss ;
        ss = (int)(bb);
        switch (ss){
//            case 9.0f ://在Float/Double上执行精确的相等匹配通常是个坏主意。
//            System.out.println("success");//一次只能匹配一种类型
//            break;
//            case "a" :
//                System.out.println("aa");
//                break;
//            case "9" :
//                System.out.println("99");
//                break;
        }
    }

    public void test(String str) {
        switch(str) {
            case "abc":
                System.out.println("abc");
                break;
            case "def":
                System.out.println("def");
                break;
            default:
                System.out.println("default");
        }
    }

//}

//反编译后的结果：2.String时不能传入null作为参数，同时case语句中使用的字符串也不能为null，
// * 因为底层是通过equals和hashCode来判断的
//public class Test {
    public void testAA(String str) {
        int i = -1;
        switch(str.hashCode()) {
            case 96354: // "abc".hashCode()
                if (str.equals("abc")) {
                    i = 0;
                }
                break;
                case 99333: // "def".hashCode()
                    if (str.equals("def")) {
                        i = 1;
                    }
                break;
            default:
                break;
        }
        switch(i) {
            case 0:
                System.out.println("abc");
                break;
                case 1:
                    System.out.println("def");
                    break;
                    default:
                        System.out.println("default");
        }
    }
}

/**
 * 注意：
 * 1.整数表达式可以是int和Integer，而byte、short、char等可以转换成int，所以
 * 也可以用。但是long和String不能转换成int，所以不能用
 * 2.String时不能传入null作为参数，同时case语句中使用的字符串也不能为null，
 * 因为底层是通过equals和hashCode来判断的
 *
         * ps：hashcode返回的是int型
         * 可以发现：进行switch的实际是hash值，然后用equals进行安全检查（因为 hash值可
         * 能会发生碰撞），所以性能不如枚举。switch支持 String其实是一个语法糖，在编译后的字
         * 节码文件中都会被还原成原生类型，并在相应位置插入了强制转换代码，底层的 JVM 在
         * switch上并没有修改。
         * 当传入switch的是 null时，在运行时对一个null调用hashCode()方法，会抛出
         * NullPointerException；如果case写的是null，那么在编译时无法求出hashcode，就会
         * 编译报错。
 * */